﻿using System;
using System.Collections.Generic;
using System.IO;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using YArchitech.Revit;
using YJKRGeometry;

namespace HangerSupport
{
	internal class HSLaySteelBeam
	{
		public HSLaySteelBeam(UIApplication uiApp)
		{
			this.m_uiApp = uiApp;
			this.m_doc = this.m_uiApp.ActiveUIDocument.Document;
			this.m_selection = this.m_uiApp.ActiveUIDocument.Selection;
			this.m_hsDraw = new HSDraw(uiApp);
			string text = "";
			string str = "热轧工字钢.rfa";
			foreach (string text2 in this.m_uiApp.Application.GetLibraryPaths().Values)
			{
				int num = text2.IndexOf("China");
				bool flag = num > 0 && num + 6 < text2.Length;
				if (flag)
				{
					text = text2.Substring(0, num + 6);
					text += "结构\\框架\\钢\\";
					text += str;
					break;
				}
			}
			bool flag2 = !File.Exists(text);
			if (flag2)
			{
				text = Utils.GetTemplateDir(this.m_uiApp) + str;
			}
			this.m_strBeamFamilyPath = text;
		}

		private FamilySymbol GetBeamSymbol()
		{
			Family family = null;
			HSFamily.IsFamilyIsLoaded(ref family, "热轧工字钢", this.m_doc);
			bool flag = family != null;
			FamilySymbol result;
			if (flag)
			{
				result = HSFamily.GetFamilySymbolDefault(family);
			}
			else
			{
				Transaction transaction = new Transaction(this.m_doc, "insertFam");
				transaction.Start();
				this.m_doc.LoadFamily(this.m_strBeamFamilyPath, out family);
				transaction.Commit();
				bool flag2 = family == null;
				if (flag2)
				{
					Utils.MessageBox(this.m_strBeamFamilyPath);
					result = null;
				}
				else
				{
					FamilySymbol familySymbolDefault = HSFamily.GetFamilySymbolDefault(family);
					result = familySymbolDefault;
				}
			}
			return result;
		}

		public static bool GetHSPositionInfo(ref XYZ vtDir, ref XYZ vtHSLink, ref XYZ ptBase, Element ele)
		{
			LocationPoint locationPoint = ele.Location as LocationPoint;
			bool flag = locationPoint == null;
			bool result;
			if (flag)
			{
				result = false;
			}
			else
			{
				ptBase = locationPoint.Point;
				ptBase = Utils.PtTo2d(ptBase);
				double num = locationPoint.Rotation;
				vtHSLink = new XYZ(Math.Cos(num), Math.Sin(num), 0.0);
				num += Math.PI*.5;
				vtDir = new XYZ(Math.Cos(num), Math.Sin(num), 0.0);
				result = true;
			}
			return result;
		}

		public List<XYZ> GetHSHungerPosition(ref HSDefineInfo def, Element ele)
		{
			List<XYZ> list = new List<XYZ>();
			def = this.m_hsDraw.GetElementHSDefine(ele);
			double num = HSFamily.mmToFeet(def.GetWideForVerLink());
			double num2 = HSFamily.mmToFeet(def.m_dPXWide);
			double num3 = HSFamily.mmToFeet(def.m_dNetWide);
			double num4 = HSFamily.mmToFeet(def.m_matVer.m_dHigh);
			XYZ xyz = null;
			XYZ xyz2 = null;
			XYZ xyz3 = null;
			HSLaySteelBeam.GetHSPositionInfo(ref xyz2, ref xyz3, ref xyz, ele);
			XYZ item = xyz - xyz3 * num / 2.0;
			XYZ item2 = xyz + xyz3 * num / 2.0;
			switch (def.m_eType)
			{
			case HSType.kDJ_DB:
			case HSType.kDJ_DG:
				list.Add(xyz);
				return list;
			case HSType.kDJ_SG:
			case HSType.kDJ_PX3:
			{
				XYZ item3 = xyz + xyz3 * (num / 2.0 - num2);
				list.Add(item);
				list.Add(item2);
				list.Add(item3);
				return list;
			}
			case HSType.kDJ_SL:
			{
				XYZ item3 = xyz + xyz3 * (num3 / 2.0 - num2 - num4 / 2.0);
				list.Add(item);
				list.Add(item2);
				list.Add(item3);
				return list;
			}
			case HSType.kDJ_ZJ:
			case HSType.kDJ_DZ:
				list.Add(item2);
				return list;
			case HSType.kDJ_DC3:
			{
				XYZ item3 = xyz;
				list.Add(item);
				list.Add(item2);
				list.Add(item3);
				return list;
			}
			}
			list.Add(item);
			list.Add(item2);
			return list;
		}

		public static bool IsPointOnCurve(Line line, XYZ pt)
		{
			XYZ xyzpoint = line.Project(pt).XYZPoint;
			return xyzpoint.IsAlmostEqualTo(pt);
		}

		public void SetHSLinkDeviceNULL(Element eleHS)
		{
			bool flag = false;
			FamilyInstance familyInstance = eleHS as FamilyInstance;
			bool flag2 = familyInstance != null;
			if (flag2)
			{
				string name = familyInstance.Symbol.Family.Name;
				bool flag3 = name.IndexOf("_DJZJ_") >= 0;
				if (flag3)
				{
					flag = true;
				}
			}
			for (int i = 0; i < 3; i++)
			{
				bool flag4 = i == 0 && flag;
				if (!flag4)
				{
					Parameter parameter = eleHS.GetParameter("连接件" + (i + 1).ToString());
					bool flag5 = parameter != null;
					if (flag5)
					{
						parameter.Set(0);
					}
				}
			}
		}

		public bool LayBeamBySingle()
		{
			FamilySymbol beamSymbol = this.GetBeamSymbol();
			bool flag = beamSymbol == null;
			bool result;
			if (flag)
			{
				result = false;
			}
			else
			{
				Parameter parameter = beamSymbol.GetParameter("d");
				bool flag2 = parameter == null;
				if (flag2)
				{
					result = false;
				}
				else
				{
					double num = parameter.AsDouble();
					PipeSelect pipeSelect = new PipeSelect(this.m_uiApp);
					List<Element> list = pipeSelect.SelectMultiHanger("请选择吊架");
					Transaction transaction = new Transaction(this.m_doc, "CreateBeam");
					transaction.Start();
					foreach (Element element in list)
					{
						HSDefineInfo elementHSDefine = this.m_hsDraw.GetElementHSDefine(element);
						bool flag3 = elementHSDefine.IsSupport();
						if (!flag3)
						{
							Parameter parameter2 = element.GetParameter(Autodesk.Revit.DB.BuiltInParameter.FAMILY_LEVEL_PARAM);
							bool flag4 = parameter2 == null;
							if (!flag4)
							{
								Level level = (Level)this.m_doc.GetElement(parameter2.AsElementId());
								bool flag5 = level == null;
								if (!flag5)
								{
									Parameter parameter3 = element.GetParameter(Autodesk.Revit.DB.BuiltInParameter.INSTANCE_FREE_HOST_OFFSET_PARAM);
									bool flag6 = parameter3 == null;
									if (!flag6)
									{
										double num2 = parameter3.AsDouble();
										parameter3.Set(num2 - num);
										this.SetHSLinkDeviceNULL(element);
										Parameter parameter4 = element.GetParameter("根部高度");
										bool flag7 = parameter4 != null;
										if (flag7)
										{
											double num3 = parameter4.AsDouble();
											bool flag8 = num3 > num;
											if (flag8)
											{
												parameter4.Set(parameter4.AsDouble() - num);
											}
										}
										bool flag9 = elementHSDefine.m_eType == HSType.kDJ_DG;
										if (flag9)
										{
											Parameter parameter5 = element.GetParameter("高");
											bool flag10 = parameter5 != null;
											if (flag10)
											{
												parameter5.Set(parameter5.AsDouble() - num);
											}
										}
										XYZ xyz = null;
										XYZ xyz2 = null;
										XYZ xyz3 = null;
										HSLaySteelBeam.GetHSPositionInfo(ref xyz2, ref xyz3, ref xyz, element);
										double num4 = 1000.0 + elementHSDefine.GetWideForVerLink();
										num4 = HSFamily.mmToFeet(num4);
										xyz = Utils.SetPtZ(xyz, level.Elevation);
										Curve curve = Line.CreateBound(xyz + xyz3 * num4 / 2.0, xyz - xyz3 * num4 / 2.0);
										UnifiedModified.ActivateFamilySymbol(beamSymbol);
										FamilyInstance elem = this.m_doc.Create.NewFamilyInstance(curve, beamSymbol, level, (Autodesk.Revit.DB.Structure.StructuralType)1);
										bool flag11 = !Geometry.IsEqual(num2, 0.0);
										if (flag11)
										{
											elem.GetParameter(Autodesk.Revit.DB.BuiltInParameter.STRUCTURAL_BEAM_END0_ELEVATION).Set(num2);
											elem.GetParameter(Autodesk.Revit.DB.BuiltInParameter.STRUCTURAL_BEAM_END1_ELEVATION).Set(num2);
										}
									}
								}
							}
						}
					}
					transaction.Commit();
					result = true;
				}
			}
			return result;
		}

		public bool IsPtInPts(List<XYZ> lstPts, XYZ ptIn)
		{
			foreach (XYZ xyz in lstPts)
			{
				bool flag = xyz.DistanceTo(ptIn) < 0.0001;
				if (flag)
				{
					return true;
				}
			}
			return false;
		}

		public bool LayBeamByMulti()
		{
			FamilySymbol beamSymbol = this.GetBeamSymbol();
			bool flag = beamSymbol == null;
			bool result;
			if (flag)
			{
				result = false;
			}
			else
			{
				Parameter parameter = beamSymbol.GetParameter("d");
				bool flag2 = parameter == null;
				if (flag2)
				{
					result = false;
				}
				else
				{
					double num = parameter.AsDouble();
					PipeSelect pipeSelect = new PipeSelect(this.m_uiApp);
					List<Element> list = pipeSelect.SelectMultiHanger("请选择吊架");
					List<Element> list2 = new List<Element>();
					bool flag3 = true;
					foreach (Element element in list)
					{
						HSDefineInfo elementHSDefine = this.m_hsDraw.GetElementHSDefine(element);
						bool flag4 = elementHSDefine.IsSupport();
						if (!flag4)
						{
							bool flag5 = elementHSDefine.IsSingleLinkPoint();
							if (flag5)
							{
								list2.Insert(list2.Count, element);
							}
							else
							{
								flag3 = false;
								list2.Insert(0, element);
							}
						}
					}
					bool flag6 = list2.Count < 2;
					if (flag6)
					{
						result = false;
					}
					else
					{
						List<Line> list3 = new List<Line>();
						List<List<XYZ>> list4 = new List<List<XYZ>>();
						bool flag7 = false;
						for (int i = 0; i < (flag3 ? 2 : 1); i++)
						{
							list3.Clear();
							list4.Clear();
							foreach (Element ele in list2)
							{
								XYZ xyz = null;
								XYZ xyz2 = null;
								XYZ xyz3 = null;
								HSLaySteelBeam.GetHSPositionInfo(ref xyz2, ref xyz3, ref xyz, ele);
								xyz2 = xyz2.Normalize();
								HSDefineInfo hsdefineInfo = new HSDefineInfo();
								List<XYZ> list5 = new List<XYZ>();
								list5 = this.GetHSHungerPosition(ref hsdefineInfo, ele);
								XYZ xyz4 = xyz2;
								bool flag8 = i == 1;
								if (flag8)
								{
									xyz4 = Utils.Rotate(xyz2, Math.PI*.5);
								}
								foreach (XYZ xyz5 in list5)
								{
									bool flag9 = false;
									for (int j = 0; j < list3.Count; j++)
									{
										bool flag10 = HSLaySteelBeam.IsPointOnCurve(list3[j], xyz5);
										if (flag10)
										{
											flag9 = true;
											list4[j].Add(xyz5);
											break;
										}
									}
									bool flag11 = !flag9;
									if (flag11)
									{
										list3.Add(Line.CreateUnbound(xyz5, xyz4));
										list4.Add(new List<XYZ>
										{
											xyz5
										});
									}
								}
							}
							foreach (List<XYZ> list6 in list4)
							{
								bool flag12 = list6.Count >= 2;
								if (flag12)
								{
									flag7 = true;
									break;
								}
							}
							bool flag13 = flag7;
							if (flag13)
							{
								break;
							}
						}
						bool flag14 = !flag7;
						if (flag14)
						{
							Utils.MessageBox("请选择平行吊架进行吊梁布置且吊点在其相同垂直线上");
							result = false;
						}
						else
						{
							Transaction transaction = new Transaction(this.m_doc, "CreateBeam");
							transaction.Start();
							Level level = null;
							double num2 = 0.0;
							for (int k = 0; k < list3.Count; k++)
							{
								List<XYZ> list7 = list4[k];
								bool flag15 = list7.Count < 2;
								if (!flag15)
								{
									list7.Sort(new XYComparer());
									for (int l = 0; l < list2.Count; l++)
									{
										Element element2 = list2[l];
										List<XYZ> list8 = new List<XYZ>();
										HSDefineInfo hsdefineInfo2 = new HSDefineInfo();
										list8 = this.GetHSHungerPosition(ref hsdefineInfo2, element2);
										foreach (XYZ ptIn in list8)
										{
											bool flag16 = this.IsPtInPts(list7, ptIn);
											if (flag16)
											{
												this.SetHSLinkDeviceNULL(element2);
												Parameter parameter2 = element2.GetParameter(Autodesk.Revit.DB.BuiltInParameter.FAMILY_LEVEL_PARAM);
												bool flag17 = parameter2 == null;
												if (!flag17)
												{
													level = (Level)this.m_doc.GetElement(parameter2.AsElementId());
													bool flag18 = level == null;
													if (!flag18)
													{
														Parameter parameter3 = element2.GetParameter(Autodesk.Revit.DB.BuiltInParameter.INSTANCE_FREE_HOST_OFFSET_PARAM);
														bool flag19 = parameter3 != null;
														if (flag19)
														{
															num2 = parameter3.AsDouble();
															parameter3.Set(num2 - num);
															Parameter parameter4 = list2[0].GetParameter("根部高度");
															bool flag20 = parameter4 != null;
															if (flag20)
															{
																double num3 = parameter4.AsDouble();
																bool flag21 = num3 > num;
																if (flag21)
																{
																	parameter4.Set(parameter4.AsDouble() - num);
																}
															}
														}
														Parameter parameter5 = list2[0].GetParameter("高");
														bool flag22 = parameter5 != null;
														if (flag22)
														{
															parameter5.Set(parameter5.AsDouble() - num);
														}
														list2.RemoveAt(l);
														l--;
														break;
													}
												}
											}
										}
									}
									double num4 = 2000.0;
									num4 = HSFamily.mmToFeet(num4);
									XYZ xyz6 = list7[0];
									XYZ xyz7 = list7[list7.Count - 1];
									XYZ xyz8 = xyz7 - xyz6;
									xyz8 = xyz8.Normalize();
									xyz6 = Utils.SetPtZ(xyz6, level.Elevation);
									xyz7 = Utils.SetPtZ(xyz7, level.Elevation);
									Curve curve = Line.CreateBound(xyz6 - xyz8 * num4 / 2.0, xyz7 + xyz8 * num4 / 2.0);
									UnifiedModified.ActivateFamilySymbol(beamSymbol);
									FamilyInstance elem = this.m_doc.Create.NewFamilyInstance(curve, beamSymbol, level, (Autodesk.Revit.DB.Structure.StructuralType)1);
									bool flag23 = !Geometry.IsEqual(num2, 0.0);
									if (flag23)
									{
										elem.GetParameter(Autodesk.Revit.DB.BuiltInParameter.STRUCTURAL_BEAM_END0_ELEVATION).Set(num2);
										elem.GetParameter(Autodesk.Revit.DB.BuiltInParameter.STRUCTURAL_BEAM_END1_ELEVATION).Set(num2);
									}
								}
							}
							transaction.Commit();
							result = true;
						}
					}
				}
			}
			return result;
		}

		private UIApplication m_uiApp;

		private Document m_doc;

		private Selection m_selection;

		private string m_strBeamFamilyPath;

		private HSDraw m_hsDraw;
	}
}
